package com.example.service.Impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.mapper.AdminMapper;
import com.example.mapper.EntrustMapper;
import com.example.mapper.ProjectMapper;
import com.example.mapper.TeamMapper;
import com.example.pojo.entity.Admin;
import com.example.pojo.entity.Entrust;
import com.example.pojo.entity.Project;
import com.example.pojo.entity.Team;
import com.example.pojo.utils.Weather;
import com.example.service.EChartsService;
import com.example.utils.AddressUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * ECharts相关数据获取
 *
 * @author ding
 * @since 2024/7/9
 */
@Service
@Slf4j
public class EChartsServiceImpl implements EChartsService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private EntrustMapper entrustMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private TeamMapper teamMapper;

    /**
     * 根据团队id获取各团队各时期的项目的总开销
     */
    public void threeDData(Integer id) {

    }

    /**
     * 获取登录者的天气数据
     */
    public Weather weatherDate() {
        //根据请求获取当前位置的经纬度
        String url = "https://restapi.amap.com/v3/ip?output=json&key=5562ac0ac15f333e7d377011603b4aa9";
        String address = AddressUtils.doGet(url);

        //经纬度
        String location = JSON.parseObject(address).getString("rectangle");
        //城市名
        String city = JSON.parseObject(address).getString("city");
        location = location.split(";")[0];

        //根据经纬度获取实时天气
        String weatherUrl = "https://devapi.qweather.com/v7/weather/now?location=" + location +"&key=8a642667c4a545d8850ab7be6b225737";
        String weather = AddressUtils.doGet(weatherUrl);

        Weather now = JSON.parseObject(weather).getObject("now", Weather.class);
        now.setCity(city);
        now.setIcon("qi-" + now.getIcon());
        return now;
    }

    @Override
    public Map<String, Object> getEntrustCount() {
        Date now = new Date();
        //今年第一天
        DateTime beginOfYear = DateUtil.beginOfYear(now);
        //今年最后一天
        DateTime endOfYear = DateUtil.endOfYear(now);

        Map<String, Object> results = new HashMap<>();
        List<Map<String, Object>> result = new ArrayList<>();

        List<Entrust> entrustsName = entrustMapper.selectList(new LambdaQueryWrapper<Entrust>()
                .select(Entrust::getName));

        List<String> nameList = entrustsName.stream().map(entrust -> entrust.getName()).collect(Collectors.toList());

        for (Entrust entrust : entrustsName) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", entrust.getName());
            map.put("type", "line");
            //从第一个月开始的本月第一天
            DateTime beginOfMonth = beginOfYear;
            List<Integer> data = new ArrayList<>();
            while (beginOfMonth.isBefore(endOfYear)){
                //本月最后一天
                MPJLambdaWrapper<Entrust> mpjLambdaWrapper = new MPJLambdaWrapper<>();
                DateTime endOfMonth = DateUtil.endOfMonth(beginOfMonth);
                mpjLambdaWrapper
                        .innerJoin(Project.class, Project::getEntrustId, Entrust::getId)
                        .eq(Entrust::getId, Project::getEntrustId)
                        .eq(Entrust::getName, entrust.getName())
                        .between(Entrust::getCreateTime, beginOfMonth, endOfMonth)
                        .groupBy(Entrust::getName);

                Long count = entrustMapper.selectCount(mpjLambdaWrapper);

                if (ObjectUtil.isNotEmpty(count)){
                    data.add(count.intValue());
                }else {
                    data.add(0);
                }
                beginOfMonth = DateUtil.offsetMonth(beginOfMonth, 1);
            }
            map.put("data", data);
            result.add(map);
        }

        results.put("Y", result);

        List<String> months = new ArrayList<>();

        while (beginOfYear.isBefore(endOfYear)) {
            String format = DateUtil.format(beginOfYear, "yyyy-MM");
            beginOfYear = DateUtil.offsetMonth(beginOfYear, 1);

            months.add(format);
        }

        results.put("X", months);

        results.put("L", nameList);

        return results;
    }

    @Override
    public Map<String, Object> getReportData() {
        Date date = new Date();

        Map<String, Object> result = new HashMap<>();

        //今日日期
        String reportDate = DateUtil.format(date, "yyyy-MM-dd");
        //本周第一天
        DateTime beginOfWeek = DateUtil.beginOfWeek(date);
        //本周最后一天
        DateTime endOfWeek = DateUtil.endOfWeek(date);
        //本月第一天
        DateTime beginOfMonth = DateUtil.beginOfMonth(date);
        //本月最后一天
        DateTime endOfMonth = DateUtil.endOfMonth(date);


        //会员总数量
        Long totalMember = adminMapper.selectCount(null);
        result.put("totalMember", totalMember);
        //今日新增会员数
        Long todayNewMember = adminMapper.selectCount(new LambdaQueryWrapper<Admin>()
                .between(Admin::getCreateTime, DateUtil.beginOfDay(date), DateUtil.endOfDay(date)));
        if (ObjectUtil.isNotEmpty(todayNewMember)){
            result.put("todayNewMember", todayNewMember);
        }else {
            result.put("todayNewMember", 0);
        }
        //这周新增会员数
        Long thisWeekNewMember = adminMapper.selectCount(new LambdaQueryWrapper<Admin>()
                .between(Admin::getCreateTime, beginOfWeek, endOfWeek));
        if (ObjectUtil.isNotEmpty(thisWeekNewMember)){
            result.put("thisWeekNewMember", thisWeekNewMember);
        }else {
            result.put("thisWeekNewMember", 0);
        }
        //本月新增会员数
        Long thisMonthNewMember = adminMapper.selectCount(new LambdaQueryWrapper<Admin>()
                .between(Admin::getCreateTime, beginOfMonth, endOfMonth));
        if (ObjectUtil.isNotEmpty(thisMonthNewMember)){
            result.put("thisMonthNewMember", thisMonthNewMember);
        }else {
            result.put("thisMonthNewMember", 0);
        }

        //今日新增项目数量
        Long todayNewProject = projectMapper.selectCount(new LambdaQueryWrapper<Project>()
                .between(Project::getCreateTime, DateUtil.beginOfDay(date), DateUtil.endOfDay(date)));
        if (ObjectUtil.isNotEmpty(todayNewProject)){
            result.put("todayNewProject", todayNewProject);
        }else {
            result.put("todayNewProject", 0);
        }
        //今日完成项目数量
        Long todayCompleteNumber = projectMapper.selectCount(new LambdaQueryWrapper<Project>()
                .eq(Project::getStatus, 4)
                .between(Project::getCreateTime, DateUtil.beginOfDay(date), DateUtil.endOfDay(date)));
        if (ObjectUtil.isNotEmpty(todayCompleteNumber)){
            result.put("todayCompleteNumber", todayCompleteNumber);
        }else {
            result.put("todayCompleteNumber", 0);
        }

        //本周新建项目数
        Long thisWeekNewNumber = projectMapper.selectCount(new LambdaQueryWrapper<Project>()
                .between(Project::getCreateTime, beginOfWeek, endOfWeek));
        if (ObjectUtil.isNotEmpty(thisWeekNewNumber)){
            result.put("thisWeekNewNumber", thisWeekNewNumber);
        }else {
            result.put("thisWeekNewNumber", 0);
        }
        //本周新建项目数
        Long thisWeekCompleteNumber = projectMapper.selectCount(new LambdaQueryWrapper<Project>()
                .eq(Project::getStatus, 4)
                .between(Project::getCreateTime, beginOfWeek, endOfWeek));
        if (ObjectUtil.isNotEmpty(thisWeekCompleteNumber)){
            result.put("thisWeekCompleteNumber", thisWeekCompleteNumber);
        }else {
            result.put("thisWeekCompleteNumber", 0);
        }

        //本月新建项目数
        Long thisMonthNewNumber = projectMapper.selectCount(new LambdaQueryWrapper<Project>()
                .between(Project::getCreateTime, beginOfMonth, endOfMonth));
        if (ObjectUtil.isNotEmpty(thisMonthNewNumber)){
            result.put("thisMonthNewNumber", thisMonthNewNumber);
        }else {
            result.put("thisMonthNewNumber", 0);
        }
        //本月新建项目数
        Long thisMonthCompleteNumber = projectMapper.selectCount(new LambdaQueryWrapper<Project>()
                .eq(Project::getStatus, 4)
                .between(Project::getCreateTime, beginOfMonth, endOfMonth));
        if (ObjectUtil.isNotEmpty(thisMonthCompleteNumber)){
            result.put("thisMonthCompleteNumber", thisMonthCompleteNumber);
        }else {
            result.put("thisMonthCompleteNumber", 0);
        }

        //热门施工队
        List<Map<String, Object>> maps = new ArrayList<>();
        //施工队集合
        List<String> nameList = teamMapper.selectList(new LambdaQueryWrapper<Team>()
                        .select(Team::getId, Team::getName))
                .stream().map(Team::getName).collect(Collectors.toList());
        for (String name : nameList) {
            Map<String, Object> map = teamMapper.selectCountByName(name);
            maps.add(map);
        }
        result.put("reportDate", reportDate);
        result.put("hotTeam", maps);

        return result;
    }
}
